package org.lboot.core.auth.aspect;

import cn.hutool.core.lang.Validator;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.lboot.core.auth.AuthService;
import org.lboot.core.auth.anno.CheckRole;
import org.lboot.core.domain.ErrMsg;
import org.lboot.core.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author kindear
 * 角色验证切面
 */
@Slf4j
@Aspect
@Component
public class CheckRoleAspect {
    @Autowired
    AuthService authService;


    /**
     * 以自定义注解作为切入
     */
    @Pointcut("@annotation(org.lboot.core.auth.anno.CheckRole)")
    public void CheckRole(){}

    @Before("CheckRole()")
    public void doBefore(JoinPoint joinPoint) {
        // 判断是否登录
        if (!authService.isLogin()){
            throw new BusinessException(HttpStatus.UNAUTHORIZED, ErrMsg.build("未登录"));
        }
        // 获取注解
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        // 获取自定义注解信息
        CheckRole checkRole = method.getAnnotation(CheckRole.class);
        // 获取所需角色标识
        String roleKey = checkRole.value();
        // 如果为空 默认需要 管理员
        if (Validator.isEmpty(roleKey)){
            roleKey = "admin";
        }
        // 设置可访问条件为 false
        boolean access = false;
        // 或条件不为空
        String perm = checkRole.orPerm();
        if (Validator.isNotEmpty(perm)){
            if (authService.hasPerm(perm)){
                access = true;
            }
        }
        // 如果还不行，再去比较角色
        if (!access && authService.hasRoleKey(roleKey)){
            access = true;
        }
        // 验证了管理员身份 adminService 配置中更多信息
        if (authService.isAdmin()){
            access = true;
        }
        if (!access){
            throw new BusinessException(HttpStatus.FORBIDDEN,ErrMsg.build("无权限"));
        }
    }

}
